package TP5;

public enum Evento {

    LLEGADA_CLIENTE() {
                @Override
                public void calcularProximaLlegada(VectorEstado nuevo) {
                    Cliente nuevoCliente = new Cliente();
                    nuevoCliente.setHoraLlegada(nuevo.getReloj());
                    nuevoCliente.setEstado(EstadoCliente.ESPERANDO_ATENCION);
                    nuevo.getExpendedor().addCliente(nuevoCliente);
                    atenderCliente(nuevo, nuevoCliente);

                    calcularProximaLlegadaCliente(nuevo);
                }
            },
    FIN_ATENCION_CLIENTE() {
                @Override
                public void calcularProximaLlegada(VectorEstado nuevo) {
            //     nuevo.setContadorPersonasNoConsiguieronGaseosaDeseada(nuevo.getContadorPersonasNoConsiguieronGaseosaDeseada() + 1);
                    //    nuevo.setContadorPersonasNoConsiguieronGaseosaYseFueron(nuevo.getContadorPersonasNoConsiguieronGaseosaYseFueron() + 1);

                    nuevo.getExpendedor().eliminarCliente();
                    nuevo.getExpendedor().setEstado(EstadoServidor.LIBRE);
                    if (nuevo.getEstadoRepositor() == EstadoRepositor.ESPERANDO) {
                        reponer(nuevo);
                    } else {
                        atenderCliente(nuevo, nuevo.getExpendedor().getClienteEnCola());
                    }

                }

                private void reponerExpendedor(VectorEstado nuevo) {
                    // falta la parte de logica de stock
                }
            },
    LLEGADA_REPOSITOR() {
                @Override
                public void calcularProximaLlegada(VectorEstado nuevo) {
                    calcularProximaLlegadaRepositor(nuevo);
                    if (nuevo.getExpendedor().getEstado() == EstadoServidor.LIBRE) {
                        reponer(nuevo);
                    }
                    if (nuevo.getExpendedor().getEstado() == EstadoServidor.OCUPADO_POR_CLIENTE) {
                        nuevo.setEstadoRepositor(EstadoRepositor.ESPERANDO);
                    }
                }
            },
    FIN_REPOSICION() {
                @Override
                public void calcularProximaLlegada(VectorEstado nuevo) {
                    if (nuevo.getExpendedor().getClientes().isEmpty()) {
                        nuevo.getExpendedor().setEstado(EstadoServidor.LIBRE);
                    } else {
                        atenderCliente(nuevo, nuevo.getExpendedor().getClienteEnCola());
                    }
                }
            },
    INICIAL() {
                @Override
                public void calcularProximaLlegada(VectorEstado nuevo) {
                    nuevo.setReloj(0);
                    calcularProximaLlegadaCliente(nuevo);
                    calcularProximaLlegadaRepositor(nuevo);
                }
            };

    abstract void calcularProximaLlegada(VectorEstado nuevo);

    private static void calcularProximaLlegadaCliente(VectorEstado nuevo) {
        nuevo.setRndLlegadaCliente();
        double tiempoEntreLLegada = nuevo.getRndLlegadaCliente() * (3.5 - 0.5) + 0.5;
        nuevo.setTiempoEntreLlegadasCliente(tiempoEntreLLegada);
        nuevo.setProximaLlegadaCliente(tiempoEntreLLegada + nuevo.getReloj());
    }

    private static void calcularProximaLlegadaRepositor(VectorEstado nuevo) {
        nuevo.setRndLlegadaRepositor();
        double tiempoEntreLlegadas = (nuevo.getRndLlegadaRepositor() * (13.0 - 11.0) + 11.0) * 60;
        nuevo.setTiempoEntreLlegadasRepositor(tiempoEntreLlegadas);
        nuevo.setProximaLlegadaRepositor(tiempoEntreLlegadas);
    }

    private static void atenderCliente(VectorEstado nuevo, Cliente nuevoCliente) {
        if (nuevoCliente == null) {
            return;
        }

        if (nuevo.getExpendedor().getEstado() == EstadoServidor.LIBRE
                && nuevo.getEstadoRepositor() != EstadoRepositor.ESPERANDO) {
            nuevo.getExpendedor().setEstado(EstadoServidor.OCUPADO_POR_CLIENTE);
            nuevoCliente.setEstado(EstadoCliente.SIENDO_ATENDIDO);
            nuevo.setRndFinAtencionCliente();
            double finAtencion = nuevo.getRndFinAtencionCliente() + 2.5;
            nuevo.setFinAtencion(finAtencion);

            nuevo.setRndTipoGaseosa();
            boolean habiaStock = nuevo.getExpendedor().hayGaseosa(nuevo.getGaseosaElegida());
            if (!habiaStock) {
                nuevo.setRndSeVa();
                if (nuevo.getSiSeVa()) {
                } else {
                    nuevo.setRndGaseosaAlternativa();
                    nuevo.getGaseosaAlternativa();
                    boolean habiaStockAlternativo = nuevo.getExpendedor().hayGaseosa(nuevo.getGaseosaAlternativa());
                    if (!habiaStockAlternativo) {
                        nuevo.getExpendedor().hayCualquierGaseosa();
                    }
                }

            }
        }

    }

    private static void reponer(VectorEstado nuevo) {
        
        nuevo.setEstadoRepositor(EstadoRepositor.REPONIENDO);
        nuevo.getExpendedor().setEstado(EstadoServidor.OCUPADO_POR_REPOSITOR);
        double tiempoReposicion = nuevo.getExpendedor().reponer();
    }

    private static void calcularTiempoReposicion(VectorEstado nuevo) {
        //  Falta implementar
        double tiempo = nuevo.getExpendedor().calcularTiempoReponer();
        nuevo.setFinReposicion(tiempo + nuevo.getReloj());
    }
}
